/*
 Copyright (C) 2012  Nikos Siatras
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.*/
package ncore_tcp_port_forward.Core;

import Extasys.DataFrame;
import Extasys.Network.TCP.Server.ExtasysTCPServer;
import Extasys.Network.TCP.Server.Listener.TCPClientConnection;
import java.net.InetAddress;
import java.util.HashMap;

/**
 *
 * @author Nikos Siatras
 */
public class TCPServer extends ExtasysTCPServer
{

    private TCPForward fMyForward;
    private HashMap fConnectedClients = new HashMap();

    public TCPServer(TCPForward myForward, String name, String description, int corePoolSize, int maximumPoolSize)
    {
        super(name, description, corePoolSize, maximumPoolSize);
        fMyForward = myForward;
    }

    @Override
    public void OnDataReceive(TCPClientConnection sender, DataFrame data)
    {
        try
        {
            if (sender.getTag() == null)
            {
                TCPClient newTCPClient = new TCPClient(sender, "", "", InetAddress.getByName(fMyForward.getRemoteIPAddress()), fMyForward.getRemotePort(), 2, 2);
                sender.setTag(newTCPClient);
                newTCPClient.Start();

                newTCPClient.SendData(data.getBytes(), 0, data.getLength());
            }
            else
            {
                TCPClient client = (TCPClient) sender.getTag();

                if (!client.isStarted())
                {
                    client.Stop();
                    client.Start();
                }
                client.SendData(data.getBytes(), 0, data.getLength());
            }
        }
        catch (Exception ex)
        {
        }
    }

    @Override
    public void OnClientConnect(TCPClientConnection client)
    {
        if (fMyForward.getAccessList().isEnabled())
        {
            String ipAndPort = client.getIPAddress().replace("/", "");
            String[] tmp = ipAndPort.split(":");
            String ipAddress = ipAndPort.replace(tmp[tmp.length - 1], "");
            ipAddress = ipAddress.substring(0, ipAddress.length() - 1);

            if (!fMyForward.getAccessList().ValidateHost(ipAddress))
            {
                client.DisconnectMe();
                System.out.println("Remote client " + ipAddress + " is not allowed!");
                return;
            }
        }

        client.setName(client.getIPAddress()); // Set a name for this client if you want to.

        if (!fConnectedClients.containsKey(client.getName()))
        {
            fConnectedClients.put(client.getName(), client);
        }

        try
        {
            TCPClient newTCPClient = new TCPClient(client, "", "", InetAddress.getByName(fMyForward.getRemoteIPAddress()), fMyForward.getRemotePort(), 2, 4);
            client.setTag(newTCPClient);
            newTCPClient.Start();
        }
        catch (Exception ex)
        {
            System.err.println(ex.getMessage());
        }
    }

    @Override
    public void OnClientDisconnect(TCPClientConnection client)
    {
        try
        {
            if (client.getTag() != null)
            {
                ((TCPClient) client.getTag()).Stop();
            }
        }
        catch (Exception ex)
        {
        }

        if (fConnectedClients.containsKey(client.getName()))
        {
            fConnectedClients.remove(client.getName());
        }
    }
}
